﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Collections;
using System.Diagnostics;
using System.Collections.Observable.DebugViews;

namespace System.Collections.Observable
{
    [DebuggerTypeProxy(typeof(ObservableListDebugView<>))]
    [DebuggerDisplay("Count = {Count}")]
    [Serializable]
    public class ObservableList<T> : ObservableListBase<T, List<T>>
    {
        // Summary:
        //     Initializes a new instance of the ObservableList<T> class
        //     that is empty and has the default initial capacity.        
        public ObservableList(): base(new List<T> ())
        {
        }

        // Summary:
        //     Initializes a new instance of the ObservableList<T> class
        //     that contains elements copied from the specified collection and has sufficient
        //     capacity to accommodate the number of elements copied.
        //
        // Parameters:
        //   collection:
        //     The collection whose elements are copied to the new list.
        //
        // Exceptions:
        //   System.ArgumentNullException:
        //     collection is null.
        public ObservableList(IEnumerable<T> collection): base(new List<T> (collection) )
        {
        }

        // Summary:
        //     Initializes a new instance of the ObservableList<T> class
        //     that is empty and has the specified initial capacity.
        //
        // Parameters:
        //   capacity:
        //     The number of elements that the new list can initially store.
        //
        // Exceptions:
        //   System.ArgumentOutOfRangeException:
        //     capacity is less than 0.        
        public ObservableList(int capacity): base(new List<T>(capacity))
        {
        }

        // Summary:
        //     Gets or sets the total number of elements the internal data structure can
        //     hold without resizing.
        //
        // Returns:
        //     The number of elements that the ObservableList<T> can contain
        //     before resizing is required.
        //
        // Exceptions:
        //   System.ArgumentOutOfRangeException:
        //     ObservableList<T>.Capacity is set to a value that is less
        //     than ObservableList<T>.Count.
        //
        //   System.OutOfMemoryException:
        //     There is not enough memory available on the system.
        public int Capacity 
        {
            get
            {
                return InternalCollection.Capacity;
            }
            set
            {
                InternalCollection.Capacity = value;
            }
        }
        
        // Summary:
        //     Adds the elements of the specified collection to the end of the ObservableList<T>.
        //
        // Parameters:
        //   collection:
        //     The collection whose elements should be added to the end of the ObservableList<T>.
        //     The collection itself cannot be null, but it can contain elements that are
        //     null, if type T is a reference type.
        //
        // Exceptions:
        //   System.ArgumentNullException:
        //     collection is null.
        public void AddRange(IEnumerable<T> collection)
        {
            InternalCollection.AddRange(collection);
            OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, 
                                                                     collection.ToList(), 
                                                                     InternalCollection.Count));
        }
        
        // Summary:
        //     Returns a read-only System.Collections.Generic.IList<T> wrapper for the current
        //     collection.
        //
        // Returns:
        //     A System.Collections.ObjectModel.ReadOnlyCollection<T> that acts as a read-only
        //     wrapper around the current ObservableList<T>.
        public ReadOnlyCollection<T> AsReadOnly()
        {
            return InternalCollection.AsReadOnly();
        }

        // Summary:
        //     Searches the entire sorted ObservableList<T> for an element
        //     using the default comparer and returns the zero-based index of the element.
        //
        // Parameters:
        //   item:
        //     The object to locate. The value can be null for reference types.
        //
        // Returns:
        //     The zero-based index of item in the sorted ObservableList<T>,
        //     if item is found; otherwise, a negative number that is the bitwise complement
        //     of the index of the next element that is larger than item or, if there is
        //     no larger element, the bitwise complement of ObservableList<T>.Count.
        //
        // Exceptions:
        //   System.InvalidOperationException:
        //     The default comparer System.Collections.Generic.Comparer<T>.Default cannot
        //     find an implementation of the System.IComparable<T> generic interface or
        //     the System.IComparable interface for type T.
        public int BinarySearch(T item)
        {
            return InternalCollection.BinarySearch(item);
        }

        // Summary:
        //     Searches the entire sorted ObservableList<T> for an element
        //     using the specified comparer and returns the zero-based index of the element.
        //
        // Parameters:
        //   item:
        //     The object to locate. The value can be null for reference types.
        //
        //   comparer:
        //     The System.Collections.Generic.IComparer<T> implementation to use when comparing
        //     elements.-or-null to use the default comparer System.Collections.Generic.Comparer<T>.Default.
        //
        // Returns:
        //     The zero-based index of item in the sorted ObservableList<T>,
        //     if item is found; otherwise, a negative number that is the bitwise complement
        //     of the index of the next element that is larger than item or, if there is
        //     no larger element, the bitwise complement of ObservableList<T>.Count.
        //
        // Exceptions:
        //   System.InvalidOperationException:
        //     comparer is null, and the default comparer System.Collections.Generic.Comparer<T>.Default
        //     cannot find an implementation of the System.IComparable<T> generic interface
        //     or the System.IComparable interface for type T.
        public int BinarySearch(T item, IComparer<T> comparer)
        {
            return InternalCollection.BinarySearch(item, comparer);
        }

        // Summary:
        //     Searches a range of elements in the sorted ObservableList<T>
        //     for an element using the specified comparer and returns the zero-based index
        //     of the element.
        //
        // Parameters:
        //   index:
        //     The zero-based starting index of the range to search.
        //
        //   count:
        //     The length of the range to search.
        //
        //   item:
        //     The object to locate. The value can be null for reference types.
        //
        //   comparer:
        //     The System.Collections.Generic.IComparer<T> implementation to use when comparing
        //     elements, or null to use the default comparer System.Collections.Generic.Comparer<T>.Default.
        //
        // Returns:
        //     The zero-based index of item in the sorted ObservableList<T>,
        //     if item is found; otherwise, a negative number that is the bitwise complement
        //     of the index of the next element that is larger than item or, if there is
        //     no larger element, the bitwise complement of ObservableList<T>.Count.
        //
        // Exceptions:
        //   System.ArgumentOutOfRangeException:
        //     index is less than 0.-or-count is less than 0.
        //
        //   System.ArgumentException:
        //     index and count do not denote a valid range in the ObservableList<T>.
        //
        //   System.InvalidOperationException:
        //     comparer is null, and the default comparer System.Collections.Generic.Comparer<T>.Default
        //     cannot find an implementation of the System.IComparable<T> generic interface
        //     or the System.IComparable interface for type T.
        public int BinarySearch(int index, int count, T item, IComparer<T> comparer)
        {
            return InternalCollection.BinarySearch(index, count, item, comparer);
        }

        // Summary:
        //     Converts the elements in the current ObservableList<T> to
        //     another type, and returns a list containing the converted elements.
        //
        // Parameters:
        //   converter:
        //     A System.Converter<TInput,TOutput> delegate that converts each element from
        //     one type to another type.
        //
        // Type parameters:
        //   TOutput:
        //     The type of the elements of the target array.
        //
        // Returns:
        //     A ObservableList<T> of the target type containing the converted
        //     elements from the current ObservableList<T>.
        //
        // Exceptions:
        //   System.ArgumentNullException:
        //     converter is null.
        public List<TOutput> ConvertAll<TOutput>(Converter<T, TOutput> converter)
        {
            return InternalCollection.ConvertAll(converter);
        }

        // Summary:
        //     Copies the entire ObservableList<T> to a compatible one-dimensional
        //     array, starting at the beginning of the target array.
        //
        // Parameters:
        //   array:
        //     The one-dimensional System.Array that is the destination of the elements
        //     copied from ObservableList<T>. The System.Array must have
        //     zero-based indexing.
        //
        // Exceptions:
        //   System.ArgumentNullException:
        //     array is null.
        //
        //   System.ArgumentException:
        //     The number of elements in the source ObservableList<T> is
        //     greater than the number of elements that the destination array can contain.        
        public void CopyTo(T[] array)
        {
            InternalCollection.CopyTo(array);
        }
        
        // Summary:
        //     Copies a range of elements from the ObservableList<T> to
        //     a compatible one-dimensional array, starting at the specified index of the
        //     target array.
        //
        // Parameters:
        //   index:
        //     The zero-based index in the source ObservableList<T> at
        //     which copying begins.
        //
        //   array:
        //     The one-dimensional System.Array that is the destination of the elements
        //     copied from ObservableList<T>. The System.Array must have
        //     zero-based indexing.
        //
        //   arrayIndex:
        //     The zero-based index in array at which copying begins.
        //
        //   count:
        //     The number of elements to copy.
        //
        // Exceptions:
        //   System.ArgumentNullException:
        //     array is null.
        //
        //   System.ArgumentOutOfRangeException:
        //     index is less than 0.-or-arrayIndex is less than 0.-or-count is less than
        //     0.
        //
        //   System.ArgumentException:
        //     index is equal to or greater than the ObservableList<T>.Count
        //     of the source ObservableList<T>.-or-The number of elements
        //     from index to the end of the source ObservableList<T> is
        //     greater than the available space from arrayIndex to the end of the destination
        //     array.
        public void CopyTo(int index, T[] array, int arrayIndex, int count)
        {
            InternalCollection.CopyTo(index, array, arrayIndex, count);
        }

        // Summary:
        //     Determines whether the ObservableList<T> contains elements
        //     that match the conditions defined by the specified predicate.
        //
        // Parameters:
        //   match:
        //     The System.Predicate<T> delegate that defines the conditions of the elements
        //     to search for.
        //
        // Returns:
        //     true if the ObservableList<T> contains one or more elements
        //     that match the conditions defined by the specified predicate; otherwise,
        //     false.
        //
        // Exceptions:
        //   System.ArgumentNullException:
        //     match is null.
        public bool Exists(Predicate<T> match)
        {
            return InternalCollection.Exists(match);
        }

        // Summary:
        //     Searches for an element that matches the conditions defined by the specified
        //     predicate, and returns the first occurrence within the entire ObservableList<T>.
        //
        // Parameters:
        //   match:
        //     The System.Predicate<T> delegate that defines the conditions of the element
        //     to search for.
        //
        // Returns:
        //     The first element that matches the conditions defined by the specified predicate,
        //     if found; otherwise, the default value for type T.
        //
        // Exceptions:
        //   System.ArgumentNullException:
        //     match is null.
        public T Find(Predicate<T> match)
        {
            return InternalCollection.Find(match);
        }

        // Summary:
        //     Retrieves all the elements that match the conditions defined by the specified
        //     predicate.
        //
        // Parameters:
        //   match:
        //     The System.Predicate<T> delegate that defines the conditions of the elements
        //     to search for.
        //
        // Returns:
        //     A ObservableList<T> containing all the elements that match
        //     the conditions defined by the specified predicate, if found; otherwise, an
        //     empty ObservableList<T>.
        //
        // Exceptions:
        //   System.ArgumentNullException:
        //     match is null.
        public List<T> FindAll(Predicate<T> match)
        {
            return InternalCollection.FindAll(match);
        }

        // Summary:
        //     Searches for an element that matches the conditions defined by the specified
        //     predicate, and returns the zero-based index of the first occurrence within
        //     the entire ObservableList<T>.
        //
        // Parameters:
        //   match:
        //     The System.Predicate<T> delegate that defines the conditions of the element
        //     to search for.
        //
        // Returns:
        //     The zero-based index of the first occurrence of an element that matches the
        //     conditions defined by match, if found; otherwise, –1.
        //
        // Exceptions:
        //   System.ArgumentNullException:
        //     match is null.
        public int FindIndex(Predicate<T> match)
        {
            return InternalCollection.FindIndex(match);
        }

        // Summary:
        //     Searches for an element that matches the conditions defined by the specified
        //     predicate, and returns the zero-based index of the first occurrence within
        //     the range of elements in the ObservableList<T> that extends
        //     from the specified index to the last element.
        //
        // Parameters:
        //   startIndex:
        //     The zero-based starting index of the search.
        //
        //   match:
        //     The System.Predicate<T> delegate that defines the conditions of the element
        //     to search for.
        //
        // Returns:
        //     The zero-based index of the first occurrence of an element that matches the
        //     conditions defined by match, if found; otherwise, –1.
        //
        // Exceptions:
        //   System.ArgumentNullException:
        //     match is null.
        //
        //   System.ArgumentOutOfRangeException:
        //     startIndex is outside the range of valid indexes for the ObservableList<T>.
        public int FindIndex(int startIndex, Predicate<T> match)
        {
            return InternalCollection.FindIndex(startIndex, match);
        }
        
        // Summary:
        //     Searches for an element that matches the conditions defined by the specified
        //     predicate, and returns the zero-based index of the first occurrence within
        //     the range of elements in the ObservableList<T> that starts
        //     at the specified index and contains the specified number of elements.
        //
        // Parameters:
        //   startIndex:
        //     The zero-based starting index of the search.
        //
        //   count:
        //     The number of elements in the section to search.
        //
        //   match:
        //     The System.Predicate<T> delegate that defines the conditions of the element
        //     to search for.
        //
        // Returns:
        //     The zero-based index of the first occurrence of an element that matches the
        //     conditions defined by match, if found; otherwise, –1.
        //
        // Exceptions:
        //   System.ArgumentNullException:
        //     match is null.
        //
        //   System.ArgumentOutOfRangeException:
        //     startIndex is outside the range of valid indexes for the ObservableList<T>.-or-count
        //     is less than 0.-or-startIndex and count do not specify a valid section in
        //     the ObservableList<T>.
        public int FindIndex(int startIndex, int count, Predicate<T> match)
        {
            return InternalCollection.FindIndex(startIndex, count, match);
        }
    
        // Summary:
        //     Searches for an element that matches the conditions defined by the specified
        //     predicate, and returns the last occurrence within the entire ObservableList<T>.
        //
        // Parameters:
        //   match:
        //     The System.Predicate<T> delegate that defines the conditions of the element
        //     to search for.
        //
        // Returns:
        //     The last element that matches the conditions defined by the specified predicate,
        //     if found; otherwise, the default value for type T.
        //
        // Exceptions:
        //   System.ArgumentNullException:
        //     match is null.
        public T FindLast(Predicate<T> match)
        {
            return InternalCollection.FindLast(match);
        }

        // Summary:
        //     Searches for an element that matches the conditions defined by the specified
        //     predicate, and returns the zero-based index of the last occurrence within
        //     the entire ObservableList<T>.
        //
        // Parameters:
        //   match:
        //     The System.Predicate<T> delegate that defines the conditions of the element
        //     to search for.
        //
        // Returns:
        //     The zero-based index of the last occurrence of an element that matches the
        //     conditions defined by match, if found; otherwise, –1.
        //
        // Exceptions:
        //   System.ArgumentNullException:
        //     match is null.
        public int FindLastIndex(Predicate<T> match)
        {
            return InternalCollection.FindLastIndex(match);
        }

        // Summary:
        //     Searches for an element that matches the conditions defined by the specified
        //     predicate, and returns the zero-based index of the last occurrence within
        //     the range of elements in the ObservableList<T> that extends
        //     from the first element to the specified index.
        //
        // Parameters:
        //   startIndex:
        //     The zero-based starting index of the backward search.
        //
        //   match:
        //     The System.Predicate<T> delegate that defines the conditions of the element
        //     to search for.
        //
        // Returns:
        //     The zero-based index of the last occurrence of an element that matches the
        //     conditions defined by match, if found; otherwise, –1.
        //
        // Exceptions:
        //   System.ArgumentNullException:
        //     match is null.
        //
        //   System.ArgumentOutOfRangeException:
        //     startIndex is outside the range of valid indexes for the ObservableList<T>.
        public int FindLastIndex(int startIndex, Predicate<T> match)
        {
            return InternalCollection.FindLastIndex(startIndex, match);
        }
        
        // Summary:
        //     Searches for an element that matches the conditions defined by the specified
        //     predicate, and returns the zero-based index of the last occurrence within
        //     the range of elements in the ObservableList<T> that contains
        //     the specified number of elements and ends at the specified index.
        //
        // Parameters:
        //   startIndex:
        //     The zero-based starting index of the backward search.
        //
        //   count:
        //     The number of elements in the section to search.
        //
        //   match:
        //     The System.Predicate<T> delegate that defines the conditions of the element
        //     to search for.
        //
        // Returns:
        //     The zero-based index of the last occurrence of an element that matches the
        //     conditions defined by match, if found; otherwise, –1.
        //
        // Exceptions:
        //   System.ArgumentNullException:
        //     match is null.
        //
        //   System.ArgumentOutOfRangeException:
        //     startIndex is outside the range of valid indexes for the ObservableList<T>.-or-count
        //     is less than 0.-or-startIndex and count do not specify a valid section in
        //     the ObservableList<T>.
        public int FindLastIndex(int startIndex, int count, Predicate<T> match)
        {
            return InternalCollection.FindLastIndex(startIndex, count, match);
        }

        // Summary:
        //     Performs the specified action on each element of the ObservableList<T>.
        //
        // Parameters:
        //   action:
        //     The System.Action<T> delegate to perform on each element of the ObservableList<T>.
        //
        // Exceptions:
        //   System.ArgumentNullException:
        //     action is null.
        public void ForEach(Action<T> action)
        {
            InternalCollection.ForEach(action);
        }

        public new List<T>.Enumerator GetEnumerator()
        {
            return InternalCollection.GetEnumerator();
        }

        // Summary:
        //     Creates a shallow copy of a range of elements in the source ObservableList<T>.
        //
        // Parameters:
        //   index:
        //     The zero-based ObservableList<T> index at which the range
        //     starts.
        //
        //   count:
        //     The number of elements in the range.
        //
        // Returns:
        //     A shallow copy of a range of elements in the source ObservableList<T>.
        //
        // Exceptions:
        //   System.ArgumentOutOfRangeException:
        //     index is less than 0.-or-count is less than 0.
        //
        //   System.ArgumentException:
        //     index and count do not denote a valid range of elements in the ObservableList<T>.
        public List<T> GetRange(int index, int count)
        {
            return GetRange(index, count);
        }

        // Summary:
        //     Searches for the specified object and returns the zero-based index of the
        //     first occurrence within the range of elements in the ObservableList<T>
        //     that extends from the specified index to the last element.
        //
        // Parameters:
        //   item:
        //     The object to locate in the ObservableList<T>. The value
        //     can be null for reference types.
        //
        //   index:
        //     The zero-based starting index of the search. 0 (zero) is valid in an empty
        //     list.
        //
        // Returns:
        //     The zero-based index of the first occurrence of item within the range of
        //     elements in the ObservableList<T> that extends from index
        //     to the last element, if found; otherwise, –1.
        //
        // Exceptions:
        //   System.ArgumentOutOfRangeException:
        //     index is outside the range of valid indexes for the ObservableList<T>.
        public int IndexOf(T item, int index)
        {
            return InternalCollection.IndexOf(item, index);
        }

        // Summary:
        //     Searches for the specified object and returns the zero-based index of the
        //     first occurrence within the range of elements in the ObservableList<T>
        //     that starts at the specified index and contains the specified number of elements.
        //
        // Parameters:
        //   item:
        //     The object to locate in the ObservableList<T>. The value
        //     can be null for reference types.
        //
        //   index:
        //     The zero-based starting index of the search. 0 (zero) is valid in an empty
        //     list.
        //
        //   count:
        //     The number of elements in the section to search.
        //
        // Returns:
        //     The zero-based index of the first occurrence of item within the range of
        //     elements in the ObservableList<T> that starts at index and
        //     contains count number of elements, if found; otherwise, –1.
        //
        // Exceptions:
        //   System.ArgumentOutOfRangeException:
        //     index is outside the range of valid indexes for the ObservableList<T>.-or-count
        //     is less than 0.-or-index and count do not specify a valid section in the
        //     ObservableList<T>.
        public int IndexOf(T item, int index, int count)
        {
            return InternalCollection.IndexOf(item, index, count);
        }

        //
        // Summary:
        //     Inserts the elements of a collection into the ObservableList<T>
        //     at the specified index.
        //
        // Parameters:
        //   index:
        //     The zero-based index at which the new elements should be inserted.
        //
        //   collection:
        //     The collection whose elements should be inserted into the ObservableList<T>.
        //     The collection itself cannot be null, but it can contain elements that are
        //     null, if type T is a reference type.
        //
        // Exceptions:
        //   System.ArgumentNullException:
        //     collection is null.
        //
        //   System.ArgumentOutOfRangeException:
        //     index is less than 0.-or-index is greater than ObservableList<T>.Count.
        public void InsertRange(int index, IEnumerable<T> collection)
        {
            InternalCollection.InsertRange(index, collection);
            OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, collection.ToList(), index));
        }

        // Summary:
        //     Searches for the specified object and returns the zero-based index of the
        //     last occurrence within the entire ObservableList<T>.
        //
        // Parameters:
        //   item:
        //     The object to locate in the ObservableList<T>. The value
        //     can be null for reference types.
        //
        // Returns:
        //     The zero-based index of the last occurrence of item within the entire the
        //     ObservableList<T>, if found; otherwise, –1.
        public int LastIndexOf(T item)
        {
            return InternalCollection.LastIndexOf(item);
        }

        // Summary:
        //     Searches for the specified object and returns the zero-based index of the
        //     last occurrence within the range of elements in the ObservableList<T>
        //     that extends from the first element to the specified index.
        //
        // Parameters:
        //   item:
        //     The object to locate in the ObservableList<T>. The value
        //     can be null for reference types.
        //
        //   index:
        //     The zero-based starting index of the backward search.
        //
        // Returns:
        //     The zero-based index of the last occurrence of item within the range of elements
        //     in the ObservableList<T> that extends from the first element
        //     to index, if found; otherwise, –1.
        //
        // Exceptions:
        //   System.ArgumentOutOfRangeException:
        //     index is outside the range of valid indexes for the ObservableList<T>.
        public int LastIndexOf(T item, int index)
        {
            return LastIndexOf(item, index);
        }
        
        // Summary:
        //     Searches for the specified object and returns the zero-based index of the
        //     last occurrence within the range of elements in the ObservableList<T>
        //     that contains the specified number of elements and ends at the specified
        //     index.
        //
        // Parameters:
        //   item:
        //     The object to locate in the ObservableList<T>. The value
        //     can be null for reference types.
        //
        //   index:
        //     The zero-based starting index of the backward search.
        //
        //   count:
        //     The number of elements in the section to search.
        //
        // Returns:
        //     The zero-based index of the last occurrence of item within the range of elements
        //     in the ObservableList<T> that contains count number of elements
        //     and ends at index, if found; otherwise, –1.
        //
        // Exceptions:
        //   System.ArgumentOutOfRangeException:
        //     index is outside the range of valid indexes for the ObservableList<T>.-or-count
        //     is less than 0.-or-index and count do not specify a valid section in the
        //     ObservableList<T>.
        public int LastIndexOf(T item, int index, int count)
        {
            return LastIndexOf(item, index, count);
        }

        // Summary:
        //     Removes the all the elements that match the conditions defined by the specified
        //     predicate.
        //
        // Parameters:
        //   match:
        //     The System.Predicate<T> delegate that defines the conditions of the elements
        //     to remove.
        //
        // Returns:
        //     The number of elements removed from the ObservableList<T>
        //     .
        //
        // Exceptions:
        //   System.ArgumentNullException:
        //     match is null.
        public int RemoveAll(Predicate<T> match)
        {
            List<T> removed = InternalCollection.FindAll(match);
            InternalCollection.RemoveAll(item => removed.Contains(item) );

            OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, removed));

            return removed.Count;
        }

        // Summary:
        //     Removes a range of elements from the ObservableList<T>.
        //
        // Parameters:
        //   index:
        //     The zero-based starting index of the range of elements to remove.
        //
        //   count:
        //     The number of elements to remove.
        //
        // Exceptions:
        //   System.ArgumentOutOfRangeException:
        //     index is less than 0.-or-count is less than 0.
        //
        //   System.ArgumentException:
        //     index and count do not denote a valid range of elements in the ObservableList<T>.
        public void RemoveRange(int index, int count)
        {
            List<T> removed = InternalCollection.GetRange(index, count);
            InternalCollection.RemoveRange(index, count);

            OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, removed, index));
        }
        
        // Summary:
        //     Reverses the order of the elements in the entire ObservableList<T>.
        public void Reverse()
        {
            throw new NotImplementedException();
        }
        
        // Summary:
        //     Reverses the order of the elements in the specified range.
        //
        // Parameters:
        //   index:
        //     The zero-based starting index of the range to reverse.
        //
        //   count:
        //     The number of elements in the range to reverse.
        //
        // Exceptions:
        //   System.ArgumentOutOfRangeException:
        //     index is less than 0.-or-count is less than 0.
        //
        //   System.ArgumentException:
        //     index and count do not denote a valid range of elements in the ObservableList<T>.
        public void Reverse(int index, int count)
        {
            throw new NotImplementedException();
        }

        // Summary:
        //     Sorts the elements in the entire ObservableList<T> using
        //     the default comparer.
        //
        // Exceptions:
        //   System.InvalidOperationException:
        //     The default comparer System.Collections.Generic.Comparer<T>.Default cannot
        //     find an implementation of the System.IComparable<T> generic interface or
        //     the System.IComparable interface for type T.
        public void Sort()
        {
            throw new NotImplementedException();
        }

        // Summary:
        //     Sorts the elements in the entire ObservableList<T> using
        //     the specified System.Comparison<T>.
        //
        // Parameters:
        //   comparison:
        //     The System.Comparison<T> to use when comparing elements.
        //
        // Exceptions:
        //   System.ArgumentNullException:
        //     comparison is null.
        //
        //   System.ArgumentException:
        //     The implementation of comparison caused an error during the sort. For example,
        //     comparison might not return 0 when comparing an item with itself.
        public void Sort(Comparison<T> comparison)
        {
            throw new NotImplementedException();
        }

        // Summary:
        //     Sorts the elements in the entire ObservableList<T> using
        //     the specified comparer.
        //
        // Parameters:
        //   comparer:
        //     The System.Collections.Generic.IComparer<T> implementation to use when comparing
        //     elements, or null to use the default comparer System.Collections.Generic.Comparer<T>.Default.
        //
        // Exceptions:
        //   System.InvalidOperationException:
        //     comparer is null, and the default comparer System.Collections.Generic.Comparer<T>.Default
        //     cannot find implementation of the System.IComparable<T> generic interface
        //     or the System.IComparable interface for type T.
        //
        //   System.ArgumentException:
        //     The implementation of comparer caused an error during the sort. For example,
        //     comparer might not return 0 when comparing an item with itself.
        public void Sort(IComparer<T> comparer)
        {
            throw new NotImplementedException();
        }

        // Summary:
        //     Sorts the elements in a range of elements in ObservableList<T>
        //     using the specified comparer.
        //
        // Parameters:
        //   index:
        //     The zero-based starting index of the range to sort.
        //
        //   count:
        //     The length of the range to sort.
        //
        //   comparer:
        //     The System.Collections.Generic.IComparer<T> implementation to use when comparing
        //     elements, or null to use the default comparer System.Collections.Generic.Comparer<T>.Default.
        //
        // Exceptions:
        //   System.ArgumentOutOfRangeException:
        //     index is less than 0.-or-count is less than 0.
        //
        //   System.ArgumentException:
        //     index and count do not specify a valid range in the ObservableList<T>.-or-The
        //     implementation of comparer caused an error during the sort. For example,
        //     comparer might not return 0 when comparing an item with itself.
        //
        //   System.InvalidOperationException:
        //     comparer is null, and the default comparer System.Collections.Generic.Comparer<T>.Default
        //     cannot find implementation of the System.IComparable<T> generic interface
        //     or the System.IComparable interface for type T.
        public void Sort(int index, int count, IComparer<T> comparer)
        {
            throw new NotImplementedException();
        }

        // Summary:
        //     Copies the elements of the ObservableList<T> to a new array.
        //
        // Returns:
        //     An array containing copies of the elements of the ObservableList<T>.
        public T[] ToArray()
        {
            return InternalCollection.ToArray();
        }

        // Summary:
        //     Sets the capacity to the actual number of elements in the ObservableList<T>,
        //     if that number is less than a threshold value.
        public void TrimExcess()
        {
            InternalCollection.TrimExcess();
        }

        // Summary:
        //     Determines whether every element in the ObservableList<T>
        //     matches the conditions defined by the specified predicate.
        //
        // Parameters:
        //   match:
        //     The System.Predicate<T> delegate that defines the conditions to check against
        //     the elements.
        //
        // Returns:
        //     true if every element in the ObservableList<T> matches the
        //     conditions defined by the specified predicate; otherwise, false. If the list
        //     has no elements, the return value is true.
        //
        // Exceptions:
        //   System.ArgumentNullException:
        //     match is null.
        public bool TrueForAll(Predicate<T> match)
        {
            return InternalCollection.TrueForAll(match);
        }

    }
}
